package example.plugins.automaton;

import java.util.ArrayList;

import framework.automaton.State;
import framework.grid.Grid;
import framework.grid.Location;

/**
 * Example of an implementation of a finite-sized square Grid that could be
 * used within the game.
 * 
 * numRows = numCols
 * 
 * @author Bill Ge, Alex Yoo, May Zhai
 */
public class SquareGrid implements Grid{
	private int numRows;
	private int numCols;
	State [][] grid;
	
	/**
	 * Constructor to make a grid of dimensions (row*col)
	 * @param row
	 * @param col
	 */
	public SquareGrid(int row){
		grid = new ConwayState[row][row];
		this.numRows = row;
		this.numCols = row;
	}
	
	public State get(Location loc) {
		if(!isValid(loc)){
			return null;
		}
		return grid[loc.getRow()][loc.getCol()];
	}

	public ArrayList getNeighbors(Location loc) {
		//assume neighbors are the 8 cells surrounding the location
		ArrayList<State> neighbors= new ArrayList<State>();
		int rows = loc.getRow();
		int cols = loc.getCol();

		for(int i = 0; i<3; i++){
			for(int j=0; j<3; j++){
				State temp = (State)get(new Location(rows-1 + i, cols-1+j));
				if(temp!=null){
					neighbors.add(temp);
				}
			}
		}
		return neighbors;
	}
	
	public int getNumCols() {
		return numCols;
	}

	public int getNumRows() {
		return numRows;
	}

	public boolean isValid(Location loc) {
		if(loc==null){
			return false;
		}
		int col = loc.getCol();
		int row = loc.getRow();
		
		if(col>=0 && col<numCols &&
				row>=0 && row<numRows){
			return true;
		}
		return false;
	}

	
	public Grid createNewGrid(int rows, int cols) {
		return new SquareGrid(rows);
	}
	
	public String toString(){
		String result = "";
		for(int i = 0; i<getNumRows(); i++){
			for(int j = 0; j<getNumCols(); j++){
				result = result + get(new Location(i,j)).toString();				
			}
			result = result + "\n";
		}
		return result;
	}

	@Override
	public boolean put(Location location, State state) {
		if(!isValid(location) || state==null){
			return false;
		}
		grid[location.getRow()][location.getCol()] = state;
		return true;
	}
}
